package com.tbit.uqbike.tergateway.wa206pkg;

import com.alibaba.fastjson.annotation.JSONField;
import com.tbit.uqbike.protocol.ATerPkgHead;
import com.tbit.uqbike.util.ErrorCode;
import io.netty.buffer.ByteBuf;

/**
 * Created by MyWin on 2017/4/27.
 */
public class WA206Head extends ATerPkgHead {

    public final static int HeadLen = 10;
    public final static short StartCode = (short) 0xAAAA;

    //region Cmd Def

    public final static byte LoginCmd = 0x01;
    public final static byte LoginCmdRsp = (byte) 0x81;

    public final static byte PosInfoCmd = 0x02;
    public final static byte PosInfoCmdRsp = (byte) 0x82;

    public final static byte BatteryInfoCmd = 0x03;
    public final static byte BatteryInfoCmdRsp = (byte) 0x83;

    public final static byte AlarmInfoCmd = 0x04;
    public final static byte AlarmInfoCmdRsp = (byte) 0x84;

    public final static byte HeartCmd = 0x05;
    public final static byte HeartCmdRsp = (byte) 0x85;

    public final static byte RemoteControlCmd = 0x06;
    public final static byte RemoteControlCmdRsp = (byte) 0x86;
    public final static byte RemoteControlCmdRspRsp = (byte) 0x96;
    public final static byte RemoteControlCmdRsp2 = (byte) 0xb6;//新增应答方式


    public final static byte GetParamCmd = 0x07;
    public final static byte GetParamCmdRsp = (byte) 0x87;

    public final static byte SetParamCmd = 0x08;
    public final static byte SetParamCmdRsp = (byte) 0x88;

    public final static byte SyncParamCmd = 0x09;
    public final static byte SyncParamCmdRsp = (byte) 0x89;

    public final static byte SmsUploadCmd = 0x0A;
    public final static byte SmsUploadCmdRsp = (byte) 0x8A;

    public final static byte RemoteSmsCmd = 0x0B;
    public final static byte RemoteSmsCmdRsp = (byte) 0x8B;

    public final static byte RemoteConVoiceCmd = 0x0C;
    public final static byte RemoteConVoiceCmdRsp = (byte) 0x8C;

    public final static byte GetFirmwareCmd = 0x0D;
    public final static byte GetFirmwareCmdRsp = (byte) 0x8D;

    public final static byte GetTerEventCmd = 0x0E;
    public final static byte GetTerEventCmdRsp = (byte) 0x8E;

    public final static byte CarStatusUploadCmd = 0x14;
    public final static byte CarStatusUploadCmdRsp = (byte) 0x94;

    public final static byte MixPosUpCmd = 0x12;
    public final static byte MixPosUpCmdRsp = (byte) 0x92;

    public final static byte TerStatusChangeUpload = 0x17;
    public final static byte TerStatusChangeUploadRsp = (byte) 0x97;

    public final static byte TerBmsFaultInfoUpload = 0x18;
    public final static byte TerBmsFaultInfoUploadRsp = (byte) 0x98;

    public final static byte TerSpotCmd = 0x15;
    public final static byte TerSpotCmdRsp = (byte) 0x95;

    public final static byte TerUploadDataCmd = 0x16;
    public final static byte TerUploadDataCmdRsp = (byte) 0x96;

    public final static byte MuPosUploadCmd = 0x19;
    public final static byte MuPosUploadCmdRsp = (byte)0x99;

    //endregion

    /**
     * 起始位
     */
    @JSONField(name = "起始码")
    public short start;
    @JSONField(name = "报文长度")
    public int pkgLen;
    @JSONField(name = "版本号")
    public byte version;
    @JSONField(name = "命令字")
    public byte cmd;
    @JSONField(name = "流水号")
    public byte serNo;
    /**
     * 保留字三个字节
     * 第三个字节的D0位用于标识终端上传的电压单位是 10mv 还是 mv。 为 0 表示单位为 1mV， 为 1 表示10mV
     * 第三个字节的D1位用于标识终端上传的远程控制指令是否需要加入设备编号， 如果为 1 则表示需要加入设备编号
     */
    @JSONField(name = "保留字")
    public int reserve;

    @Override
    public String toString() {
        return "WA206Head{" +
                "version=" + version +
                ", cmd=" + cmd +
                ", serNo=" + serNo +
                ", reserve=" + reserve +
                '}';
    }

    /**
     * 终端控制回应报文是否包含设备编号
     *
     * @return
     */
    public boolean TerRspExistMno() {
        if ((reserve & 0x2) == 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 获取电压的单位 基础单位是mv
     *
     * @return
     */
    public int GetEUUnit() {
        if ((reserve & 0x1) == 0) {
            return 1;
        } else {
            return 10;
        }
    }

    /**
     * 主版本
     *
     * @return
     */
    public byte GetMainVersion() {
        return (byte) (version >> 4);
    }

    /**
     * 次版本
     *
     * @return
     */
    public byte GetSubVersion() {
        return (byte) ((version & 0xff) & 0xf);
    }

    /**
     * 获取协议号
     *
     * @return
     */
    public byte GetVersion() {
        return (byte) (this.version >>> 2);
    }

    /**
     * 是否是wa206c版本
     *
     * @return
     */
    @JSONField(name = "WA206C协议")
    public boolean isWA206CVersion() {
        return ((GetVersion() & 0x1) != 0);
    }

    @JSONField(name = "111位置修改版本")
    public boolean is111PosInfo() {
        return (GetVersion() == 7);
    }

    @JSONField(name = "100位置修改版本")
    public boolean is100PosInfo() {
        return (GetVersion() == 4);
    }

    @JSONField(name = "扩展编号")
    public boolean isTidExVersion() {
        return ((GetVersion() & (1 << 1)) != 0);
    }

    public boolean isPosEx() {
        return ((GetVersion() & (1 << 2)) != 0);
    }

    public int InitPkg(ByteBuf in, int inv, int len) {
        this.start = in.getShort(inv);
        inv += 2;
        this.pkgLen = in.getShort(inv) & 0xffff;
        inv += 2;
        this.version = in.getByte(inv);
        inv++;
        this.cmd = in.getByte(inv);
        inv++;
        this.serNo = in.getByte(inv);
        inv++;
        this.reserve = in.getMedium(inv);
        inv += 3;
        return ErrorCode.OK;
    }

    public static WA206Head getWA206Head(byte version, int reserve, byte serNo) {
        WA206Head wa206Head = new WA206Head();
        wa206Head.start = StartCode;
        wa206Head.pkgLen = 0;
        wa206Head.version = version;
        wa206Head.cmd = 0;
        wa206Head.serNo = serNo;
        wa206Head.reserve = reserve;
        return wa206Head;
    }

    public ByteBuf writePkgByte(ByteBuf byteBuf) {
        byteBuf.writeShort(this.start);
        byteBuf.writeShort(this.pkgLen);
        byteBuf.writeByte(this.version);
        byteBuf.writeByte(this.cmd);
        byteBuf.writeByte(this.serNo);
        byteBuf.writeMedium(this.reserve);
        return byteBuf;
    }

    @Override
    public int getSerNo() {
        return (this.serNo & 0xff);
    }

    /**
     * 是否是小木吉的TID
     *
     * @param mno
     * @return
     */
    public static boolean isXiaomuji(String mno) {
        if (mno != null && mno.startsWith("EC")) {
            return true;
        }
        return false;
    }
}
